/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package concurrent.queue;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author harker777
 */
class Producer implements Runnable {

	@Override
	public void run() {
		Random random = new Random();
		String name = Thread.currentThread().getName();
		while (true) {
			synchronized (CommonDataStorage.class) {
				System.out.println(name + " starting to work:");
				Boolean dataHasPlace = findPlace();

				if (dataHasPlace) {
					produce();
					CommonDataStorage.class.notify();
				} else {
					try {
						System.out.println("Nowhere to produce");
						CommonDataStorage.class.wait();
					} catch (InterruptedException ex) {
					}
				}

			}
			try {
				Integer sleepTime = (Integer) (random.nextInt(CommonDataStorage.getProducerMaxWaitTime()));
				Thread.sleep(sleepTime);
			} catch (InterruptedException ex) {
				Logger.getLogger(ProducerConsumerDemo.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
	}

	private Boolean findPlace() {
		Integer candidate = 0;

		if (CommonDataStorage.getCurrentProducing() == CommonDataStorage.getQueueSize() - 1) {
			candidate = 0;
		} else {
			candidate = CommonDataStorage.getCurrentProducing() + 1;
		}
		if (CommonDataStorage.getData()[candidate] == 0) {
			CommonDataStorage.setCurrentProducing(candidate);
			return true;
		} else {
			return false;
		}
	}

	private void produce() {
		Integer totalNumber = CommonDataStorage.getTotalNumber();
		Integer currentProducing = CommonDataStorage.getCurrentProducing();
		int[] data = CommonDataStorage.getData();
		System.out.println("Produced item " + totalNumber + " into slot #" + currentProducing);
		data[currentProducing] = totalNumber;
		ProducerConsumerDemoUtils.print(data);
		CommonDataStorage.setCurrentNumber(CommonDataStorage.getCurrentNumber() + 1);
		CommonDataStorage.setTotalNumber(CommonDataStorage.getTotalNumber() + 1);
		totalNumber += 1;
	}
}
